﻿#include "tlv.h"
#include "utils/String/hexbin.h"
#include <QObject>


Tlv::Tlv(TlvTag tlvTag, const QByteArray &tlvValue)
    : m_tag(tlvTag)
    , m_value(tlvValue)
    , m_isReq(false)
{

}

TlvTag Tlv::tag() const
{
    return m_tag;
}

QByteArray Tlv::value() const
{
    return m_value;
}

QByteArray Tlv::toBytes() const
{
    QByteArray ret;
    uint16_t tag16 = static_cast<uint16_t>(m_tag);
    uint16_t len = m_value.length();
    ret.append(getHByte(tag16));
    ret.append(getLByte(tag16));
    ret.append(getHByte(len));
    ret.append(getLByte(len));
    ret.append(m_value);
    return ret;
}

QString Tlv::toLog() const
{
    if (m_isReq) {
        QString log = QString(R"(-----------Tlv_Req-----------
Tag    : 0x%1 (%2)
Len    : %3
Event  : Request
Value  :
%4
)").arg(QString::number(m_tag, 16).toUpper()).arg(Tlv::tagStr(m_tag)).arg(m_value.length()).arg(HexBin::hexFormat(m_value));
        return log;
    } else {
        QString log = QString(R"(-----------Tlv_Rep-----------
Tag    : 0x%1 (%2)
Len    : %3
Event  : Response
Value  :
%4
)").arg(QString::number(m_tag, 16).toUpper()).arg(Tlv::tagStr(m_tag)).arg(m_value.length()).arg(HexBin::hexFormat(m_value));
        return log;
    }
}

bool Tlv::isIicFeedback() const
{
    return TlvTag::Tlv_IIC_feedback == m_tag;
}

bool Tlv::isIicCall() const
{
    return TlvTag::Tlv_IIC_IIC_CALL == m_tag;
}

void Tlv::setRequestMode(bool req) const
{
    m_isReq = req;
}

QString Tlv::tagStr(const TlvTag &tag)
{
    QString str;
    switch (tag) {
    case Tlv_seq_id:
        str = "seq_id";
        break;
    case Tlv_status:
        str = "status";
        break;
    case Tlv_reserve:
        str = "reserve";
        break;
    case Tlv_IIC_feedback:
        str = "IIC_feedback";
        break;
    case Tlv_IIC_IIC_CALL:
        str = "IIC_IIC_CALL";
        break;
    case Tlv_Interrupt_resp:
        str = "Interrupt_resp";
        break;
    case Tlv_MCU_RESET:
        str = "MCU_RESET";
        break;
    case Tlv_TOUCH_EVENT:
        str = "TOUCH_EVENT";
        break;
    case Tlv_MCU_Product_STATUS:
        str = "MCU_Product_STATUS";
        break;
    case Tlv_MCU_Release_TimeStamp:
        str = "MCU_Release_TimeStamp";
        break;
    case Tlv_MCU_RAM_Data:
        str = "MCU_RAM_Data";
        break;
    case Tlv_MCU_Product_STD_Frame:
        str = "MCU_Product_STD_Frame";
        break;
    case Tlv_MCU_Product_EXT_Frame:
        str = "MCU_Product_EXT_Frame";
        break;
    case Tlv_MCU_Product_REC_Frame:
        str = "MCU_Product_REC_Frame";
        break;
    case Tlv_MCU_Warning:
        str = "MCU_Warning";
        break;
    case Tlv_MCU_String:
        str = "MCU_String";
        break;
    case Tlv_MCU_Dump:
        str = "MCU_Dump";
        break;
    case Tlv_MCU_DumpControl:
        str = "MCU_DumpControl";
        break;
    case Tlv_MCU_ROM_Data:
        str = "MCU_ROM_Data";
        break;
    case Tlv_MCU_BOOT_APP_REQ:
        str = "MCU_BOOT_APP_REQ";
        break;
    case Tlv_MCU_BOOT_APP_RSP:
        str = "MCU_BOOT_APP_RSP";
        break;
    case Tlv_MCU_Program_REQ:
        str = "MCU_Program_REQ";
        break;
    case Tlv_MCU_Program_RSP:
        str = "MCU_Program_RSP";
        break;
    case Tlv_MCU_Enter_BOOT:
        str = "MCU_Enter_BOOT";
        break;
    case Tlv_MCU_CAN_TX_REQ:
        str = "MCU_CAN_TX_REQ";
        break;
    case Tlv_MCU_CAN_TX_RSP:
        str = "MCU_CAN_TX_RSP";
        break;
    case Tlv_MCU_CAN_RX:
        str = "MCU_CAN_RX";
        break;
    case Tlv_MCU_SET_IO:
        str = "MCU_SET_IO";
        break;
    case Tlv_MCU_ADC_REQ:
        str = "MCU_ADC_REQ";
        break;
    case Tlv_MCU_ADC_RSP:
        str = "MCU_ADC_RSP";
        break;
    case Tlv_MCU_REQ_RSP:
        str = "MCU_REQ_RSP";
        break;
    case Tlv_PL_IIC_RSP:
        str = "PL_IIC_RSP";
        break;
    case Tlv_IntnCall_RSP:
        str = "IntnCall_RSP";
        break;
    case Tlv_PL_IIC_REQ:
        str = "PL_IIC_REQ";
        break;
    case Tlv_IntnCall:
        str = "IntnCall";
        break;
    default:
        str = "Unknown";
        break;
    }

    return str;
}

Tlv Tlv::tlvNull()
{
    return Tlv(TlvTag::Tlv_NULL, QByteArray());
}

const QList<TlvTag> Tlv::allTags()
{
    static const QList<TlvTag> tags = {
        Tlv_seq_id                     ,      // 通讯ID
        Tlv_status                     ,      // 通讯状态
        Tlv_reserve                    ,      // 通讯预留
        Tlv_IIC_feedback               ,      // IICA0反馈
        Tlv_IIC_IIC_CALL               ,      // IICA0调用
        Tlv_Interrupt_resp             ,      // 中断响应
        Tlv_MCU_RESET                  ,      // MCU复位
        Tlv_TOUCH_EVENT                ,      // 标准触摸报点
        Tlv_MCU_Product_STATUS         ,      // mcu产品(项目)状态，例如adc、ntc、背光fault等
        Tlv_MCU_Release_TimeStamp      ,      // 软件释放时间戳
        Tlv_MCU_RAM_Data               ,      // mcu指定RAM的值
        Tlv_MCU_Product_STD_Frame      ,      // 产品通讯_标准帧
        Tlv_MCU_Product_EXT_Frame      ,      // 产品通讯_扩展帧
        Tlv_MCU_Product_REC_Frame      ,      // 产品通讯_接收帧
        Tlv_MCU_Warning                ,      // mcu发出的警告消息（具体场景自定义）
        Tlv_MCU_String                 ,      // mcu发出的字符串信息（具体场景自定义）
        Tlv_MCU_Dump                   ,      // 前4字节为地址，mcu将自身内存传出，需先发tag19
        Tlv_MCU_DumpControl            ,      // dump控制信息（开始结束、起始地址等）
        Tlv_MCU_ROM_Data               ,      // mcu指定ROM的值
        Tlv_MCU_BOOT_APP_REQ           ,      // 请求boot还是APP
        Tlv_MCU_BOOT_APP_RSP           ,      // [1=boot, 2=APP] + N字节版本信息
        Tlv_MCU_Program_REQ            ,      // 4字节地址(大端) + N字节数据
        Tlv_MCU_Program_RSP            ,      // 4字节地址(大端) + 1字节结果(0成功，其它失败原因)
        Tlv_MCU_Enter_BOOT             ,      // 请求进入boot
        Tlv_MCU_CAN_TX_REQ             ,      // 15765消息
        Tlv_MCU_CAN_TX_RSP             ,      // TBD
        Tlv_MCU_CAN_RX                 ,      // 15765消息
        Tlv_MCU_SET_IO                 ,      // 2字节编号 + 1字节类型(1高低电平,2PWM) + 2字节值(65535=PWM100%)
        Tlv_MCU_ADC_REQ                ,      // 2字节编号
        Tlv_MCU_ADC_RSP                ,      // 2字节编号 + 2字节ADC值
        Tlv_MCU_REQ_RSP                ,      // 通用响应: 2字节cmdid + 1字节状态; 状态: 1未定义; 2未实现; 3非自身功能
        Tlv_PL_IIC_RSP                 ,      // 产线IIC响应，60805(ED85)响应
        Tlv_IntnCall_RSP               ,      // 内置函数请求响应，60806(ED86)响应
        Tlv_PL_IIC_REQ                 ,      // 产线IIC请求
        Tlv_IntnCall                   ,      // 内置函数请求
    };
    return tags;
}
